using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using NavigateExample.ViewModels;
using NavigateExample.Services.Navigation;

namespace NavigateExample.Services
{
    /// <summary>
    /// 基于View的导航服务实现类
    /// </summary>
    public class NavigationService : ObservableObject, INavigationService
    {
        private readonly IServiceProvider _serviceProvider;
        // 导航载体控件
        private ContentControl? _contentControl;
        // 导航到的页面
        private UserControl? _currentPage;
        public UserControl? CurrentPage
        {
            get => _currentPage;
            private set
            {
                if (SetProperty(ref _currentPage, value))
                {
                    CurrentPageChanged?.Invoke();
                }
            }
        }
        //该事件是预留接口，每当导航到新页面时CurrentPage属性实际发生变化时触发
        //允许外部组件监听页面变化，而无需直接依赖导航实现细节
        public event Action? CurrentPageChanged;
        public NavigationService(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
        }
        public void SetNavigationControl(ContentControl contentControl) => _contentControl = contentControl;
        // 简单导航到指定View
        public void Navigate<T>() where T : UserControl =>  Navigate<T>(new NavigationParameters(), null);
        // 带参数导航到指定View
        public void Navigate<T>(NavigationParameters parameters) where T : UserControl => Navigate<T>(parameters, null);
        // 带参数和回调的导航到指定View
        //1.判断ContenControl是否可用2.检查当前页面是否允许导航离开CanNavigateFrom
        //3.调用当前页面的OnNavigatedFrom通知导航离开4.创建导航目标实例GetRequiredService<TView>
        //5.将ContentControl设置为导航目标页面6.调用目标页面OnNavigatedTo通知导航到达
        public void Navigate<T>(NavigationParameters parameters, Action<INavigationResult>? callback) where T : UserControl
        {
            try
            {
                if (_contentControl == null)
                {
                    var failureResult = NavigationResult.CreateFailure("ContentControl未初始化，无法导航");
                    callback?.Invoke(failureResult);
                    return;
                }
                // 检查当前页面的ViewModel是否允许导航离开
                if (CurrentPage?.DataContext is INavigationAware currentAware)
                {
                    if (!currentAware.CanNavigateFrom(parameters))
                    {
                        var failureResult = NavigationResult.CreateFailure("当前页面不允许导航离开");
                        callback?.Invoke(failureResult);
                        return;
                    }
                }
                // 通知当前页面的ViewModel导航离开
                if (CurrentPage?.DataContext is INavigationAware currentNavigationAware)
                {
                    currentNavigationAware.OnNavigatedFrom(parameters);
                }
                // 创建新页面
                var newPage = _serviceProvider.GetRequiredService<T>();
                if (newPage == null)
                {
                    var failureResult = NavigationResult.CreateFailure($"无法创建视图 {typeof(T).Name}，请检查是否已正确注册到依赖注入容器中。");
                    callback?.Invoke(failureResult);
                    return;
                }
                // 设置导航
                CurrentPage = newPage;
                _contentControl.Content = CurrentPage;
                // 通知新页面的ViewModel导航到达
                if (newPage.DataContext is INavigationAware newNavigationAware)
                {
                    newNavigationAware.OnNavigatedTo(parameters);
                }
                var successResult = NavigationResult.CreateSuccess();
                callback?.Invoke(successResult);
            }
            catch (Exception ex)
            {
                var failureResult = NavigationResult.CreateFailure($"导航过程中发生错误: {ex.Message}", ex);
                callback?.Invoke(failureResult);
            }
        }
        // 仅带回调的导航到指定View
        public void Navigate<T>(Action<INavigationResult> callback) where T : UserControl
        {
            Navigate<T>(new NavigationParameters(), callback);
        }
        // 直接导航到指定页面
        public void Navigate(UserControl page)
        {
            if (_contentControl == null)
            {
                return;
            }
                
            CurrentPage = page;
            _contentControl.Content = page;
        }
    }
}